package collection

type treeBuild[D TreeID, V any] struct {
	data *[]TreeElement[D, V]
}
type treeSyncBuild[D TreeID, V any] struct {
	data *[]TreeElement[D, V]
}

// TreeBuild 通过扁平化节点数据构建一个树结构，自动检测环路过滤循环数据
//   - data 节点数据
//   - rootID 根节点ID, 通常为零值
//   - 注意: ID不能为零值, 数值类型不能为负数
func TreeBuild[D TreeID, V any](data []TreeElement[D, V], rootID D) *TreeNode[D, V] {
	root := NewTree[D, V]()
	if len(data) < 1 {
		return root
	}
	b := new(treeBuild[D, V])
	b.data = &data

	b.buildNode(root, rootID)
	return root
}

// buildNode 构建一个树结构数据，插入下级子节点
func (b treeBuild[D, V]) buildNode(node *TreeNode[D, V], PID D) {
	if list, ok := b.lookNode(PID); ok {
		for _, v := range list {
			if n, err := node.Push(v.ID, v.Value); err == nil {
				b.buildNode(n, v.ID)
			}
		}
	}
}

// lookNode 寻找同级节点
func (b treeBuild[D, V]) lookNode(PID D) (list []TreeElement[D, V], ok bool) {
	list = make([]TreeElement[D, V], 0)
	for _, v := range *(b.data) {
		if v.PID == PID {
			list = append(list, v)
		}
	}
	if len(list) > 0 {
		ok = true
	}
	return
}

// TreeSyncBuild 通过扁平化节点数据构建一个树结构，自动检测环路过滤循环数据
//   - data 节点数据
//   - rootID 根节点ID, 通常为零值
//   - 注意: ID不能为零值, 数值类型不能为负数
func TreeSyncBuild[D TreeID, V any](data []TreeElement[D, V], rootID D) *TreeNodeSync[D, V] {
	root := NewTreeSync[D, V]()
	if len(data) < 1 {
		return root
	}
	b := new(treeSyncBuild[D, V])
	b.data = &data

	b.buildNode(root, rootID)
	return root
}

// buildNode 构建一个树结构数据，插入下级子节点
func (b treeSyncBuild[D, V]) buildNode(node *TreeNodeSync[D, V], PID D) {
	if list, ok := b.lookNode(PID); ok {
		for _, v := range list {
			if n, err := node.Push(v.ID, v.Value); err == nil {
				b.buildNode(n, v.ID)
			}
		}
	}
}

// lookNode 寻找同级节点
func (b treeSyncBuild[D, V]) lookNode(PID D) (list []TreeElement[D, V], ok bool) {
	list = make([]TreeElement[D, V], 0)
	for _, v := range *(b.data) {
		if v.PID == PID {
			list = append(list, v)
		}
	}
	if len(list) > 0 {
		ok = true
	}
	return
}
